package ain.standard;

import util.Vector;
import environment.Pitch;
import environment.Team;
import environment.player.Player;

public class StandardGuardAntibody extends StandardAbstractAntibody
{
	private static int ID = 5;
	
	public StandardGuardAntibody(Player player, Pitch pitch)
	{
		super(player, pitch);
	}

	public void execute()
	{
		// walks to nearest point on line between ball and goal; two exceptions
		// 1. player is in front of ball (ball closer to goal than player)
		// solution: walk towards homeGoal
		// 2. intersection point is outside pitch (player not within area covered by orthogonal projection of line)
		// solution: go towards y-middle of pitch
				
		// 1st exception:
		if (isInFrontOfBall())
		{
			player.walk(player.getHomeGoal());
		}
		else
		{
			Vector ball = pitch.getBall().getPosition();
			Vector ballGoalLine = Vector.substract(ball, player.getHomeGoal());
			Vector target = Vector.intersection(ball, ballGoalLine, player.getPosition(), Vector.orthogonal(ballGoalLine));
			
			// 2nd exception
			if (target.getX() < 0 || target.getX() > pitch.getWidth())
			{
				player.walk(new Vector(player.getPosition().getX(), pitch.getHeight()/2));
			}
			else
			{
				player.walk(target);
			}
		}
	}
	
	private boolean isInFrontOfBall()
	{	
		if (player.getTeam().equals(Team.HOME))
		{
			return (player.getPosition().getX() - pitch.getBall().getPosition().getX()) < 0;
		}
		else return (player.getPosition().getX() - pitch.getBall().getPosition().getX()) > 0;
	}
	
	protected double distBallRatioValue(double ratio)
	{
		return (ratio <= 2) ? (ratio / 2) : 1;
	}
	
	protected double distBallGoalValue(double zoneNumber)
	{
		if (zoneNumber <= (1.0 / 3) * 5)
		{
			return 1 - (zoneNumber / ((1.0 / 3) * 5)); 
		}
		
		return 0;
	}
	
	protected double imprDistBallGoalValue(double zoneNumber)
	{
		if (zoneNumber <= (1 + (4.0/3.0)))
		{
			return 1 - ((zoneNumber - 1) / (4.0/3.0)); 
		}
		
		return 0;
	}

	protected double distBallPlayerValue(double distance)
	{
		if (distance <= FAR_RADIUS)
		{
			return distance / FAR_RADIUS;
		}
		else return 1;
	}
	
	public int getID()
	{
		return ID;
	}
	
	public String toString()
	{
		return "Guard";
	}
}
